<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>Configuration &middot; Theos</title>
	<meta name="viewport" content="initial-scale=1">
	<meta name="theme-color" content="#382b42">
	<link rel="stylesheet" type="text/css" href="assets/style-c8af8a04be2058be41d4157721a624bcd1543cc5641394fb0e9450c62a04e09d.css">
	<link rel="icon" href="assets/favicon-447ec328b50bd5d64f09e1f06fe07532f924f274bd5de6567a43690bf494c99a.svg" sizes="any" type="image/svg+xml">

</head>

<body>
	<header>
	<div class="container">
		<h1>
			<a href="#">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 781 224">
					<title>Theos</title>
					<path d="M155.2 18.4H2.6v36.3H54V218h47.4V54.7h49.2l4.6-36.3zM263 60.2c-18 0-31.7 7.2-44 21V-.3l-45.6 4.6V218H219V113.2c8-12.4 16.3-19.6 26.4-19.6 8.6 0 14.4 4.3 14.4 20.4v104h45.5V106.3c0-29-16-46-42.4-46zm210 78.3c0 5-.4 11.8-1 16.4h-94.4c2.8 27 15.8 34.2 34.5 34.2 13 0 24-4.3 37-13.6l19 25.4c-15.2 12-35 21.4-59.6 21.4-51 0-77-33-77-80.7 0-45.6 25-82 71.5-82 43.5.3 70.5 29 70.5 78.5zm-44.7-11v-2c-.3-20.7-6.7-35-24.8-35-15.3 0-24 9.4-26.2 37h51zm137-67.3c46.7 0 75 30 75 81.5 0 49-28.3 81.2-75 81.2-46.3 0-74.8-30-74.8-82 0-49 28.2-81 74.8-81zm0 33.4c-18.4 0-27.6 14.7-27.6 47.8 0 34 9.2 48 27.6 48 18.5 0 27.7-14.6 27.7-47.7 0-34-9.2-48-27.7-48zm156-33.4c-38.7 0-62.6 20.4-62.6 46.6 0 23.6 15 39.2 45.2 47.8 27 7.8 32 11 32 21.4 0 9.2-8.8 14.4-22 14.4-15 0-29-6-41-15L651 200c15 14 37.4 23 64 23 38 0 68-18.6 68-50.3 0-27.4-17-40-47.3-48.7-27.3-8-31.4-11.6-31.4-19.7 0-7 6-11.5 18.5-11.5 13 0 25.7 4.3 37.5 11.8l17-25.6c-14-11.6-34-18.8-56-18.8z" fill="currentColor" fill-rule="evenodd"/>
				</svg>
			</a>
		</h1>

		<p class="header-tagline">A cross-platform build system for creating iOS, macOS, Linux, and Windows programs.</p>
	</div>
</header>


	<main>
		<div class="container">
			<div class="row flex-md-row-reverse">
				<article class="col-md-9">
					<h1>Configuration</h1>
					<p>Theos, and your project(s), can be configured in a few differents ways:</p>
<ul>
  <li>Via a shared configuration file</li>
  <li>At runtime via project Makefiles</li>
  <li>At runtime by passing variables to <code class="language-plaintext highlighter-rouge">make</code></li>
</ul>

<h2 id="theosrc"><code class="language-plaintext highlighter-rouge">.theosrc</code></h2>

<p>Variables that are specific to your own setup (e.g., Xcode/an SDK, device IP, etc) should not be placed in your project makefile as it may hinder others from building your project. Instead, these variables should be placed in <code class="language-plaintext highlighter-rouge">.theosrc</code>, a makefile that is read and executed during an early stage of Theos’ <code class="language-plaintext highlighter-rouge">common.mk</code>.</p>

<p><code class="language-plaintext highlighter-rouge">.theosrc</code> must be created by the user at <code class="language-plaintext highlighter-rouge">$HOME/.theosrc</code> or <code class="language-plaintext highlighter-rouge">~/.theosrc</code>.</p>

<h2 id="utilizing-theos-makefile-rules">Utilizing Theos’ makefile rules</h2>

<p>Makefile rules are defined as:</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">targets</span><span class="o">:</span> <span class="nf">prerequisites</span>
	<span class="nb">command</span>
	<span class="nb">command</span>
</code></pre></div></div>

<p>Theos utilizes a variety of such rules internally, many of which can also be utilized by users by adding the following to your project’s Makefile:</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">rule-name</span><span class="o">::</span>
	your_command
	your_command
</code></pre></div></div>

<p>Such rule names include:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">before-clean</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-clean</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-clean</code></li>
  <li><code class="language-plaintext highlighter-rouge">before-all</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-all</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-all</code></li>
  <li><code class="language-plaintext highlighter-rouge">before-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">before-package</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-package</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-package</code></li>
  <li><code class="language-plaintext highlighter-rouge">before-$(THEOS_CURRENT_INSTANCE)-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-$(THEOS_CURRENT_INSTANCE)-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-$(_THEOS_CURRENT_TYPE)-stage</code></li>
  <li><code class="language-plaintext highlighter-rouge">before-$(THEOS_CURRENT_INSTANCE)-all</code></li>
  <li><code class="language-plaintext highlighter-rouge">after-$(THEOS_CURRENT_INSTANCE)-all</code></li>
  <li><code class="language-plaintext highlighter-rouge">internal-$(_THEOS_CURRENT_TYPE)-all</code></li>
</ul>

<h2 id="schemas-schemata">Schemas (“Schemata”)</h2>

<p>Schemas are a way to manage a group of specific master variables which can have their effect easily turned on or off. An example is the built-in debug schema, which when enabled adds extra options to <code class="language-plaintext highlighter-rouge">CFLAGS</code>, <code class="language-plaintext highlighter-rouge">LDFLAGS</code>, and <code class="language-plaintext highlighter-rouge">SWIFTFLAGS</code>.</p>

<p>They are enabled via <code class="language-plaintext highlighter-rouge">THEOS_SCHEMA</code>, with a space-separated list of the schemas you’d like to enable.</p>

<p>The schema is described by specifying what variables have their values affected by its enabling. Doing so can be done by declaring a variable with the format <code class="language-plaintext highlighter-rouge">schema.VARIABLE</code>, so that enabling schema will do changes to a possible query of variable <code class="language-plaintext highlighter-rouge">VARIABLE</code> (e.g., <code class="language-plaintext highlighter-rouge">DEBUG.CFLAGS</code>). <code class="language-plaintext highlighter-rouge">VARIABLE</code> must be used in Theos for the changes to have an effect. See <a href="https://github.com/theos/theos/blob/master/makefiles/common.mk">common.mk</a> for schema logic implementation.</p>

<p>Example:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Enabling schema1 will add the '-DSCHEMA1ENABLED' additional compiler flags.
schema1.CFLAGS = -DSCHEMA1ENABLED
</code></pre></div></div>

<h2 id="utilizing-theos-message-commands">Utilizing Theos’ message commands</h2>

<p>Theos utilizes a variety of custom <code class="language-plaintext highlighter-rouge">echo</code> and <code class="language-plaintext highlighter-rouge">printf</code> commands which it defines as variables in $THEOS_MAKE_PATH/messages.mk. These can be utilized by users in their own project makefiles if so desired.</p>

<p>Such variables include:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">$(ECHO_BEGIN)</code>
    <ul>
      <li>Defines start of command user wants printed after it has run</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(ECHO_NOTHING)</code>
    <ul>
      <li>Defines start of command user wants printed after it has run
        <ul>
          <li>Note that when verbosity is enabled, <code class="language-plaintext highlighter-rouge">set -o pipefail</code> is run beforehand</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(ECHO_END)</code>
    <ul>
      <li>Defines end of command user wrapped in <code class="language-plaintext highlighter-rouge">$(ECHO_BEGIN)</code> or <code class="language-plaintext highlighter-rouge">$(ECHO_NOTHNG)</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(STDERR_NULL_REDIRECT)</code>
    <ul>
      <li>Defined as <code class="language-plaintext highlighter-rouge">2&gt; /dev/null</code>
        <ul>
          <li>Disabled if verbosity is enabled</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(STDOUT_NULL_REDIRECT)</code>
    <ul>
      <li>Defined as <code class="language-plaintext highlighter-rouge">&gt; /dev/null</code>
        <ul>
          <li>Disabled if verbosity is enabled</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT)</code>
    <ul>
      <li>Defined as <code class="language-plaintext highlighter-rouge">printf "\e[0;36m==&gt; \e[1;36mNotice:\e[m %s\n"</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_WARNING)</code>
    <ul>
      <li>Defined as <code class="language-plaintext highlighter-rouge">printf "\e[0;33m==&gt; \e[1;33mWarning:\e[m %s\n"</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_ERROR)</code>
    <ul>
      <li>Defined as <code class="language-plaintext highlighter-rouge">printf "\e[0;31m==&gt; \e[1;31mError:\e[m %s\n"</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_RED)</code>
    <ul>
      <li>A red-colored print statement
        <ul>
          <li>Disabled if COLOR=0</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_GREEN)</code>
    <ul>
      <li>Disabled if COLOR=0</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_YELLOW)</code>
    <ul>
      <li>Disabled if COLOR=0</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_BLUE)</code>
    <ul>
      <li>Disabled if COLOR=0</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_MAGENTA)</code>
    <ul>
      <li>Disabled if COLOR=0</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(PRINT_FORMAT_CYAN)</code>
    <ul>
      <li>Disabled if COLOR=0</li>
    </ul>
  </li>
</ul>

<h2 id="utilizing-gnu-make">Utilizing GNU Make</h2>

<p>Theos relies on GNU Make to function. This means that all standard Make capabilities can be used with Theos as if they were being used in any standard Unix makefile.</p>

<p>Some of the more relevant capabilities include:</p>
<ul>
  <li>Print formatting</li>
  <li>Running shell commands</li>
  <li>File acquisition via wildcards</li>
  <li>Setting variables to varying degrees of project depth</li>
  <li>Utilizing conditional statements</li>
</ul>

<h3 id="print-formatting">Print formatting</h3>

<p>The following can be used in your Makefile(s) as desired within Theos’ makefile rules:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">$(info some text here)</code>
    <ul>
      <li>Will print <code class="language-plaintext highlighter-rouge">some text here</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(warning some text here)</code>
    <ul>
      <li>Will print <code class="language-plaintext highlighter-rouge">Makefile:&lt;line#&gt;: some text here</code></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">$(error some text here)</code>
    <ul>
      <li>Will print <code class="language-plaintext highlighter-rouge">Makefile:&lt;line#&gt;: *** some text here.  Stop.</code></li>
      <li>Note: will stop the build</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">@echo "some text here"</code>
    <ul>
      <li>Will print <code class="language-plaintext highlighter-rouge">some text here</code> using <a href="https://man.cameronkatri.com/echo.1"><code class="language-plaintext highlighter-rouge">echo(1)</code></a></li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">@printf "some text here"</code>
    <ul>
      <li>Will print <code class="language-plaintext highlighter-rouge">some text here</code> without a trailing newline (i.e., “\n”). Note that <a href="https://man.cameronkatri.com/printf.1"><code class="language-plaintext highlighter-rouge">printf(1)</code></a> uses a format string.</li>
    </ul>
  </li>
</ul>

<h3 id="running-shell-commands">Running shell commands</h3>

<p>If you need to run commands from within a makefile, there are two main ways:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">$(shell command)</code>
    <ul>
      <li>Will return the output of “command” for use</li>
    </ul>
  </li>
  <li>Typing the command as-is
    <ul>
      <li>Will print both the command being run and the output, if relevant</li>
    </ul>
  </li>
</ul>

<h3 id="file-acquisition-via-wildcards">File acquisition via wildcards</h3>

<p>For your project instance (where XXX is your project_name), the XXX_FILES variable is required for non-null project types. If your project has a large number of files and/or a complex directory structure, typing out each file by hand would be arduous. To work around this, makefiles have wildcards. The syntax is as follows:</p>

<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">$(wildcard</span> <span class="err">pattern-to-match)</span>
</code></pre></div></div>

<p>An example usage of this would be</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">XXX_FILES</span> <span class="o">=</span> <span class="nf">$(</span><span class="nb">wildcard</span> <span class="k">*</span>.m<span class="nf">)</span> <span class="nf">$(</span><span class="nb">wildcard</span> files/<span class="k">*</span>.x<span class="nf">)</span>
</code></pre></div></div>

<p>Assuming you have a complex directory structure and don’t feel like messing with pattern matching, you can also shell out to <code class="language-plaintext highlighter-rouge">find</code>.</p>

<p>An example usage of this would be</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">XXX_FILES</span> <span class="o">=</span> <span class="nf">$(</span><span class="nb">shell</span> find <span class="nb">.</span> <span class="nt">-type</span> f <span class="nt">-name</span> <span class="s2">"*.m"</span><span class="nf">)</span>
</code></pre></div></div>

<h3 id="setting-variables-to-varying-degrees-of-project-depth">Setting variables to varying degrees of project depth</h3>

<p>In order to configure your project, you will almost certainly need to modify variables in your project’s makefile(s).</p>

<p>Variables can be kept local to their project’s instance by declaring them normally.</p>

<p>An example of this would be</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">ARCHS</span> <span class="o">=</span> arm64 arm64e
</code></pre></div></div>

<p>If you want a variable to apply to all instances within a project (i.e., apply to subprojects), then you can preface the variable declaration with <code class="language-plaintext highlighter-rouge">export</code>. Such exported variables will likely want to be in your root makefile so that the subproject makefiles do not need duplicate declarations.</p>

<p>An example usage of this would be</p>
<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export </span><span class="nv">TARGET</span> <span class="o">=</span> iphone:clang:latest:12.0
</code></pre></div></div>

<h3 id="utilizing-conditional-statements">Utilizing conditional statements</h3>

<p>Whether you’re declaring variables yourself or modifying predefined ones, conditional statements can come in handy for complex configuration.</p>

<p>Makefile <code class="language-plaintext highlighter-rouge">if</code> statements follow the syntax:</p>

<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ifeq</span> <span class="nv">($(variable), $(variable-to-check-against))</span>
    <span class="nv">something</span><span class="o">=</span>0
<span class="err">else</span> <span class="k">ifneq</span> <span class="nv">($(variable2), $(variable-to-check-against))</span>
    <span class="nv">something</span><span class="o">=</span>1
<span class="err">else</span> <span class="k">ifdef</span> <span class="nv">($(variable3))</span>
    <span class="nv">something</span><span class="o">=</span>2
<span class="err">else</span> <span class="k">ifndef</span> <span class="nv">($(variable4))</span>
    <span class="nv">something</span><span class="o">=</span>3
<span class="k">else</span>
    <span class="nv">something</span><span class="o">=</span>4
<span class="k">endif</span>
</code></pre></div></div>

				</article>

				<aside class="col-md-3">
					<ul>
  
  <li>
    
      <a href="./index.html">Home</a>
    
    
  </li>
  
  <li>
    
      <a href="./Installation.html">Installation</a>
    
    
      <ul>
        
          <li>
            <a href="./Installation-iOS.html">
              iOS
              
            </a>
          </li>
        
          <li>
            <a href="./Installation-macOS.html">
              macOS
              
            </a>
          </li>
        
          <li>
            <a href="./Installation-Linux.html">
              Linux & Windows
              
            </a>
          </li>
        
          <li>
            <a href="./Upgrading-from-legacy-Theos.html">
              Upgrading from legacy Theos
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <span>Usage</span>
    
    
      <ul>
        
          <li>
            <a href="./Concepts.html">
              Concepts
              
            </a>
          </li>
        
          <li>
            <a href="./Configuration.html">
              Configuration
              
            </a>
          </li>
        
          <li>
            <a href="./Commands.html">
              Commands
              
            </a>
          </li>
        
          <li>
            <a href="./Packaging.html">
              Packaging
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <a href="./Features.html">Features</a>
    
    
      <ul>
        
          <li>
            <a href="./NIC.html">
              NIC
              
            </a>
          </li>
        
          <li>
            <a href="./NIC-Syntax.html">
              NIC Syntax
              
            </a>
          </li>
        
          <li>
            <a href="./dm.pl.html">
              dm.pl
              
            </a>
          </li>
        
          <li>
            <a href="./Swift.html">
              Swift
              
            </a>
          </li>
        
          <li>
            <a href="./Modules.html">
              Modules
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <span>Tweak Development</span>
    
    
      <ul>
        
          <li>
            <a href="./Logos.html">
              Logos
              
            </a>
          </li>
        
          <li>
            <a href="./Logos-Syntax.html">
              Logos Syntax
              
            </a>
          </li>
        
          <li>
            <a href="./logify.pl.html">
              Logify
              
            </a>
          </li>
        
          <li>
            <a href="./Logos-File-Extensions.html">
              File Extensions
              
            </a>
          </li>
        
          <li>
            <a href="./Logos-Hook-Splitting.html">
              Hook Splitting
              
            </a>
          </li>
        
          <li>
            <a href="https://orion.theos.dev/" target="_blank" rel="noopener">
              Orion
              
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M1 11L11 1"/>
                  <path d="M2.5 1H11V9.5"/>
                </svg>
              
            </a>
          </li>
        
          <li>
            <a href="./Rootless.html">
              Rootless
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <span>Technical</span>
    
    
      <ul>
        
          <li>
            <a href="./Structure.html">
              Structure
              
            </a>
          </li>
        
          <li>
            <a href="./Variables.html">
              Variables
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <a href="./Help.html">Help</a>
    
    
      <ul>
        
          <li>
            <a href="./FAQ.html">
              FAQ
              
            </a>
          </li>
        
          <li>
            <a href="./Parallel-Building.html">
              Parallel Building
              
            </a>
          </li>
        
          <li>
            <a href="./arm64e-Deployment.html">
              arm64e Deployment
              
            </a>
          </li>
        
          <li>
            <a href="./License.html">
              License
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
  <li>
    
      <span>See also</span>
    
    
      <ul>
        
          <li>
            <a href="https://theapplewiki.com/" target="_blank" rel="noopener">
              The Apple Wiki
              
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M1 11L11 1"/>
                  <path d="M2.5 1H11V9.5"/>
                </svg>
              
            </a>
          </li>
        
          <li>
            <a href="https://www.reddit.com/r/jailbreakdevelopers" target="_blank" rel="noopener">
              /r/jailbreakdevelopers
              
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M1 11L11 1"/>
                  <path d="M2.5 1H11V9.5"/>
                </svg>
              
            </a>
          </li>
        
          <li>
            <a href="https://github.com/theiostream/theos-ref" target="_blank" rel="noopener">
              theos-ref (legacy docs)
              
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M1 11L11 1"/>
                  <path d="M2.5 1H11V9.5"/>
                </svg>
              
            </a>
          </li>
        
      </ul>
    
  </li>
  
</ul>

				</aside>
			</div>
		</div>
	</main>

	<footer role="navigation">
	<ul class="footer-sub-links">
		<li><a href="./">Docs</a></li>
		<li><a href="./Help.html">Get Help</a></li>
		<li><a href="https://github.com/theos" rel="me">GitHub</a></li>
		<li><a href="https://procursus.social/@theos" rel="me">@theos@procursus.social</a></li>
		<li><a href="https://twitter.com/theosdev" rel="me">@theosdev</a></li>
		<li><a href="/discord">Discord</a></li>
	</ul>

	<div class="footer-legal">
		Copyright &copy; Theos.
		<br>
		<a href="https://github.com/theos/theos.dev">Edit on GitHub</a>
	</div>
</footer>

</body>
</html>
